<template>
  <f7-popup
    class="popup-file-upload"
    :opened="popupOpened"
    @popup:closed="popupOpened = false"
  >
    <f7-page>
      <f7-navbar title="文件上传">
        <f7-nav-right>
          <f7-link popup-close>关闭</f7-link>
        </f7-nav-right>
      </f7-navbar>
      <f7-block-title>文件列表</f7-block-title>
      <f7-list media-list>
        <f7-list-item
          link="#"
          v-for="file in files"
          :key="file.id"
          :title="file.name"
        >
          <img slot="media" v-if="file.thumb" :src="file.thumb" width="40" />
          <img
            slot="media"
            v-if="!file.thumb"
            :src="getThumb(file)"
            width="40"
          />
          <div slot="subtitle">
            <span>{{ file.size | fileSize }}</span>
            <span class="right text-color-red" v-if="file.error">{{ formatError(file) }}</span>
            <span class="right" v-else-if="file.success">上传成功</span>
            <span class="right" v-else-if="file.active">上传中...{{ file.progress }}%</span>
            <span class="right" v-else>等待中...</span>
          </div>
          <f7-progressbar
            slot="text"
            color="red"
            :progress="parseFloat(file.progress)"
          ></f7-progressbar>
        </f7-list-item>
      </f7-list>
      <f7-list inset>
        <file-upload
          class="button col"
          :post-action="postAction"
          :input-id="uploadId"
          :chunk-enabled="chunkEnabled"
          :chunk="{
            action: chunkAction,
            minSize: chunkMinSize * 1048576,
            maxActive: chunkMaxActive,
            maxRetries: chunkMaxRetries,
            finishBody: params,
            handler: handlerClass,
          }"
          :extensions="extensions"
          :accept="accept"
          :multiple="multiple"
          :size="size"
          v-model="files"
          @input-filter="inputFilter"
          @input-file="inputFile"
          :ref="uploadId"
          :data="params"
        >
          选择文件
        </file-upload>
      </f7-list>
    </f7-page>
  </f7-popup>
</template>
<script>
import _ from "lodash";
import ImageCompressor from "image-compressor.js";
import FileUpload from "vue-upload-component";
import formatter from "../framework/formatter";
import ChunkUploadHandler from "../polyfill/ChunkUploadHandler";
export default {
  components: {
    FileUpload
  },
  props: {
    params: {
      type: Object,
      default: {}
    },
    uploadId: {
      type: String,
      default: 'file'
    },
    extensions: {
      type: String
    },
    accept: {
      type: String
    },
    multiple: {
      type: Boolean,
      default: true
    },
    size: {
      type: Number,
      default: 1024 * 1024 * 10
    },
    postAction: {
      type: String,
      default: "/api/base/FileUpload/uploadFile"
    },
    chunkAction: {
      type: String,
      default: "/api/base/ChunkUpload/upload"
    }
  },
  data() {
    return {
      files: [],
      chunkEnabled: true,
      // 1MB by default
      chunkMinSize: 0,
      chunkMaxActive: 3,
      chunkMaxRetries: 5,
      popupOpened: false,
      uploadAuto: true,
      handlerClass: ChunkUploadHandler,
      autoCompress: 2048
    };
  },
  methods: {
    getThumb(file) {
      if (file.thumb) {
        return file.thumb;
      } else if (file.name) {
        let extension = file.name.substring(file.name.lastIndexOf(".") + 1);
        if (
          extension &&
          "avi,doc,docx,jpg,mp4,pdf,png,ppt,pptx,rar,txt,xls,xlsx,zip"
            .split(",")
            .includes(extension.toLowerCase())
        ) {
          return "/static/img/file/" + extension.toLowerCase() + ".png";
        }
      }
      return "/static/img/file/default.png";
    },
    formatError(file) {
      var error = "上传失败";
      switch (file.error) {
        case "size":
          error = "文件太大，不超过" + formatter.formatFileSize(this.size);
          break;
        case "extension":
          error = "文件类型不符，只允许" + this.accept;
          break;
        case "timeout":
          error = "网络超时";
          break;
        case "abort":
          error = "用户放弃";
          break;
        case "network":
          error = "网络连接失败";
          break;
        case "server":
          error = "服务器错误";
          break;
        case "denied":
          error = "请求无效";
          break;
        default:
          error = "上传失败";
          break;
      }
      return error;
    },
    inputFilter(newFile, oldFile, prevent) {
      if (newFile && !oldFile) {
        // Before adding a file
        // 添加文件前
        // Filter system files or hide files
        // 过滤系统文件 和隐藏文件
        if (/(\/|^)(Thumbs\.db|desktop\.ini|\..+)$/.test(newFile.name)) {
          return prevent();
        }
        // Filter php html js file
        // 过滤 php html js 文件
        if (/\.(php5?|html?|jsx?)$/i.test(newFile.name)) {
          return prevent();
        }
        // Automatic compression
        // 自动压缩
        if (
          newFile.file &&
          newFile.type.substr(0, 6) === "image/" &&
          this.autoCompress > 0 &&
          this.autoCompress < newFile.size
        ) {
          newFile.error = "compressing";
          const imageCompressor = new ImageCompressor(null, {
            convertSize: Infinity,
            maxWidth: 512,
            maxHeight: 512
          });
          imageCompressor
            .compress(newFile.file)
            .then(file => {
              this.$refs[this.uploadId].update(newFile, {
                error: "",
                file,
                size: file.size,
                type: file.type
              });
            })
            .catch(err => {
              this.$refs[this.uploadId].update(newFile, {
                error: err.message || "compress"
              });
            });
        }
      }
      if (newFile && (!oldFile || newFile.file !== oldFile.file)) {
        // Create a blob field
        // 创建 blob 字段
        newFile.blob = "";
        let URL = window.URL || window.webkitURL;
        if (URL && URL.createObjectURL) {
          newFile.blob = URL.createObjectURL(newFile.file);
        }
        // Thumbnails
        // 缩略图
        newFile.thumb = "";
        if (newFile.blob && newFile.type.substr(0, 6) === "image/") {
          newFile.thumb = newFile.blob;
        }
      }
    },
    // add, update, remove File Event
    inputFile(newFile, oldFile) {
      if (newFile && oldFile) {
        // update
        if (newFile.active && !oldFile.active) {
          // beforeSend
          // min size
          if (
            newFile.size >= 0 &&
            this.minSize > 0 &&
            newFile.size < this.minSize
          ) {
            this.$refs[this.uploadId].update(newFile, { error: "size" });
          }
        }
        if (newFile.progress !== oldFile.progress) {
          // progress
        }
        if (newFile.error && !oldFile.error) {
          // error
        }
        if (newFile.success && !oldFile.success) {
          // success
          let rep = newFile.response;
          if (Object.keys(rep).includes('success') && rep.success) {
            // 上传成功
            this.$emit("success", newFile);
          } else {
            // 上传失败
            this.$f7.dialog.alert(newFile.response.message || '服务器不允许该文件上传');
            this.files.pop();
          }
        }
      }
      if (!newFile && oldFile) {
        // remove
        if (oldFile.success && oldFile.response.id) {
          // $.ajax({
          //   type: 'DELETE',
          //   url: '/upload/delete?id=' + oldFile.response.id,
          // })
        }
      }
      // Automatically activate upload
      if (
        Boolean(newFile) !== Boolean(oldFile) ||
        oldFile.error !== newFile.error
      ) {
        if (this.uploadAuto && !this.$refs[this.uploadId].active) {
          this.$refs[this.uploadId].active = true;
        }
      }
    }
  }
};
</script>
<style scoped>
.chunk-loading {
  margin: -12px;
  display: flex;
  width: calc(100% + 24px);
}
.chunk-loading .chunk-loading-part {
  height: 25px;
  line-height: 25px;
  flex: 1;
  background: #ccc;
  font-size: 14px;
  color: white;
  text-align: center;
}
.chunk-loading .chunk-loading-part.chunk-loading-part__uploaded {
  background: #28a745;
}
.file-uploads {
  width: 100%;
}
</style>